<?php
class sfActionsCreatix extends sfActions
{

	const MSG_FILTRAGEM_EFETUADA  = 'Filtragem Efetuada.';
	const FILTER_INSTANCE_NAME = 'filter';
	const FILTER_HTML_KEY = 'filter';
	const FILTER_SESSION_USER_ATTRIBUTE = 'filter';

	const FILTER_SUCCESS = 1;
	const FILTER_ERROR =   2;
	const LIMIT_PAGE_DATA_TABLE = 10;

	### UTIL

	public function getRequestParameter($name, $default = null)
	{
		if(is_array($name)) {
			$valor = $this->requestParameterHolder->get($name[0]);
			if(isset($valor[$name[1]])) {
				return $valor[$name[1]];
			}
			else {
				return $default;
			}
		}
		else {
			return $this->requestParameterHolder->get($name, $default);
		}
	}

	public function erroGenerico() {
		print_r($this->getRequest()->getErrors());
		die();
	}
	### FILTROS E PAGINA

	/**
	 * Set the actual page in the session if this is not setted
	 *
	 * @return actual page
	 */
	protected function _setActualPage() {
		$ns = $this->getModuleName();
		if($this->hasRequestParameter('pg_num')) {
			$paginaAtual = $this->getRequestParameter('pg_num');
		}
		else {
			$paginaAtual =
			$this->getUser()->getAttribute('pg_num',1,$ns);
		}
		$this->getUser()->setAttribute('pg_num',$paginaAtual,$ns);
		return $paginaAtual;
	}

	/**
	 * Get the filter from or create a new in the session
	 *
	 * @param array $defaultValues
	 * @return filter
	 */

	protected function _getFilter($defaultValues = array()) {
		$ns = $this->getModuleName();
		if($this->getUser()->hasAttribute(self::FILTER_SESSION_USER_ATTRIBUTE,$ns)) {
			$filter = unserialize(
			$this->getUser()->getAttribute(self::FILTER_SESSION_USER_ATTRIBUTE,null,$ns)
			);
		}
		else {
			$filter = new Filtro(
			array(),
			$defaultValues
			);
			$filter->setCulture($this->getUser()->getCulture());
		}
		return $filter;
	}

	public function executeFilter() {
		$ns = $this->getModuleName();
		$filter = new Filtro(
		$this->getRequestParameter(self::FILTER_SESSION_USER_ATTRIBUTE)
		);
		$filter->setCulture($this->getUser()->getCulture());
		$this->getUser()->setAttribute('pg_num',1,$ns);
		$this->setFlash('mensagem',self::MSG_FILTRAGEM_EFETUADA,false);
		$this->getUser()->setAttribute(
		self::FILTER_SESSION_USER_ATTRIBUTE,
		serialize($filter),
		$ns
		);
		return $this->route(self::FILTER_SUCCESS);
	}

	public function handleErrorFilter() {
		return $this->route(self::FILTER_ERROR);
	}

	### UPLOAD / IMAGENS E CACHE

	protected function receberUpload(
	&$objeto,
	$campo,
	$nome_parametro,
	$obrigatorio = false,
	$caminho = ''
	) {
		if ($this->getRequest()->hasFile($nome_parametro))
		{
			$sucesso = true;
			$nome_arquivo  = $this->getRequest()->getFileName($nome_parametro);
			//$fileSize  = $this->getRequest()->getFileSize($fileName);
			//$fileType  = $this->getRequest()->getFileType($fileName);
			$uploadDir = sfConfig::get('sf_upload_dir');
			$this->getRequest()->moveFile($nome_parametro, $uploadDir.DIRECTORY_SEPARATOR.$caminho.$nome_arquivo);
			if($this->getRequest()->hasFileError($nome_parametro)) {
				$codErro = $this->getRequest()->getFileError($nome_parametro);
				if(
				$obrigatorio || $codErro != 4
				) {
					switch($codErro) {
						case 1:
							$msg = 'Arquivo maior do que a configuração do servidor.';
							break;
						case 2:
							$msg = 'Arquivo maior do que a configuração do formul�rio.';
							break;
						case 3:
							$msg = 'Upload incompleto.';
							break;
						case 4:
							$msg = 'Arquivo obrigatório';
							break;
					}
					$this->getRequest()->setError(
					$nome_parametro,
					$msg
					);
					$sucesso = false;
				}
			}
			else {
				$objeto->set($campo, $nome_arquivo);
			}
			return $sucesso;
		}
		else {
			if($this->getRequest()->isXmlHttpRequest()) {
				$mensagem = 'Uploads não funcionam com HttpRequest';
			}
			else {
				$mensagem = 'O campo de upload não foi enviado.';
			}
			$this->getRequest()->setError(
			$nome_parametro,
			$mensagem
			);
			return false;
		}
		return false;
	}

	protected function verifyUpload(
	$parameterName,
	$required = false
	) {
		$msg = null;
		if ($this->getRequest()->hasFile($parameterName))
		{
			$sucesso = true;
			$nome_arquivo  = $this->getRequest()->getFileName($parameterName);
			if($this->getRequest()->hasFileError($parameterName)) {
				$codErro = $this->getRequest()->getFileError($parameterName);
				if(
				$required || $codErro != 4
				) {
					switch($codErro) {
						case 1:
							$msg = 'Arquivo maior do que a configuração do servidor.';
							break;
						case 2:
							$msg = 'Arquivo maior do que a configuração do formulário.';
							break;
						case 3:
							$msg = 'Upload incompleto.';
							break;
						case 4:
							$msg = 'Arquivo obrigatório';
							break;
					}
					$sucesso = false;
				}
			}
		}
		else {
			if($this->getRequest()->isXmlHttpRequest()) {
				$msg = 'Uploads não funcionam com HttpRequest';
			}
			else {
				$msg = 'O campo de upload não foi enviado.';
			}
			$sucesso = false;
		}
		$tmp_file = $this->getRequest()->getFileValue($parameterName, 'tmp_name');
		if($tmp_file !== '') { // string(0) neste framework quer dizer que o usuário quer remover a imagem
			if(!is_uploaded_file($tmp_file)) {
				$msg = 'O arquivo não é um upload válido.';
				$sucesso = false;
			}
		}
		if($msg) {
			$this->getRequest()->setError(
			$parameterName,
			$msg
			);
		}
		return $sucesso;
	}

	protected function clearCache($pkValue,$className,$fieldName) {
		$caminho = $this->cacheDir($className,$fieldName).$pkValue;
		$caminhos = glob($caminho.'_thumb*');
		$caminhos[] = $caminho;
		foreach($caminhos as $caminho) {
			if(file_exists($caminho)) {
				if(!is_writeable($caminho)) {
					throw new Exception('O sistema está sem permissão para limpar o arquivo de cache.');
				}
				unlink($caminho);
			}
		}
	}

	protected function cacheDir($className,$fieldName) {
		return
		sfConfig::get('sf_cache_dir')
		.DIRECTORY_SEPARATOR
		.strtolower($className).'_'.$fieldName
		.DIRECTORY_SEPARATOR;
	}

	protected function showImage(
	$pkValue,
	$className,
	$fieldName,
	$msgNoImage,
	$resizeValues = null
	) {
		if($resizeValues !== null) {
			if(is_array($resizeValues) && count($resizeValues) == 2) {
				$width = $resizeValues[0];
				$height = $resizeValues[1];
				$generateThumb = true;
			}
			else {
				trigger_error('O parâmetro resizeValues deve ser um array com [width,heigth]');
			}
		}
		else {
			$generateThumb = false;
		}
		sfConfig::set('sf_web_debug', false);
		$dir = $this->cacheDir($className,$fieldName);
		if($generateThumb) {
			$caminhoThumb = $dir.$pkValue.'_thumb_'.$width.'_'.$height;
			$caminhoOriginal = $dir.$pkValue;
		}
		$caminhoOriginal = $dir.$pkValue;

		if(!file_exists($dir)) {
			if(!is_writeable($dir)) {
				throw new Exception('O diretório de cache está sem permissão de gravação.');
			}
			mkdir($dir,0777);
		}
		if(!file_exists($caminhoOriginal)) {
			$obj = Doctrine::getTable($className)->find($pkValue);
			$streamOrigem = $obj->get($fieldName);
			if(is_resource($streamOrigem)) {
				$destResource = fopen($caminhoOriginal,'w+');
				fwrite($destResource, stream_get_contents($streamOrigem));
				fclose($destResource);
				$existe = true;
			}
			else {
				$existe = false;
			}
		}
		else {
			$existe = true;
		}
		if($existe && $generateThumb) {
			$thumbnail = new sfThumbnail($width, $height);
			$thumbnail->loadFile($caminhoOriginal);
			$thumbnail->save($caminhoThumb);
		}
		if($existe) {
			header("Content-Type: image");
			if($generateThumb) {
				return $this->renderText(file_get_contents($caminhoThumb));
			}
			else {
				return $this->renderText(file_get_contents($caminhoOriginal));
			}
		}
		else {
			return $this->renderText($msgNoImage);
		}
	}

	###  HTTP REQUEST


	protected function listaJsonChavesDescricoes($ar_valores) {
		$this->getResponse()->setHttpHeader(
      "Content-type", "application/json"
      );
      $this->getResponse()->setContent(
      '('.
      json_encode(
      array(
            'chaves'=>array_keys($ar_valores),
            'descricoes'=>array_values($ar_valores)
      )
      )
      .')'
      );
      return sfView::NONE;
	}

	protected function atualizarDivComHtml(
	$nome_div = null, // se null aqui, no js deve ser obrigat�rio.
	$html)
	{
		$this->partial = $html;
		$this->header_json($nome_div);
		$this->setTemplate('partial');
		$this->setLayout(false);
	}

	protected function atualizarDivComPartial(
	$nome_div = null, // se null aqui, no js deve ser obrigat�rio.
	$caminho_partial,
	$ar_valores)
	{
		##precisa renderizar primeiro pois define as mensagens que n�o est�o no form.
		sfLoader::loadHelpers('Partial');
		$this->partial =
		get_partial(
		$caminho_partial,
		$ar_valores
		);
		$this->header_json($nome_div);
		$this->setTemplate('partial');
		$this->setLayout(false);
	}

	protected function atualizarDivComComponent(
	$nome_div = null, // se null aqui, no js deve ser obrigat�rio.
	$moduleName,
	$componentName,
	$values)
	{
		##precisa renderizar primeiro pois define as mensagens que n�o est�o no form.
		sfLoader::loadHelpers('Partial');
		$this->partial =
		get_component(
		$moduleName,
		$componentName,
		$values
		);
		$this->header_json($nome_div);
		$this->setTemplate('partial');
		$this->setLayout(false);
	}

	protected function header_json($nome_div_atualizar = false) {
		##monta o cabecalho, indicando as mensagens e o div a atualizar.
		$ar = array();
		$ar['mensagem'] = $this->mensagens_json();
		if($nome_div_atualizar) {
			$ar['div_atualizar']=$nome_div_atualizar;
		}
		$this->getResponse()->setHttpHeader(
      "X-JSON", 
      '('.json_encode($ar).')'
      );
	}

	protected function mensagens_json() {
		##pega todas as mensagens.
		$errosMostrados = $this->request->getParameterHolder()->get('errosMostrados');
		$mensagem = '';
		foreach($this->request->getErrors() as $campo=>$erro) {
			if(!in_array($campo,$errosMostrados)) {
				$mensagem .=  "Erro não mostrado:".$erro.'.';
			}
		}
		if($this->request->getParameterHolder()->has('errosMostrados')) {
			$mensagem .= 'Por favor corrija os erros indicados.';
		}
		$mensagem .= $this->getFlash('mensagem');
		$mensagem .= $this->getFlash('erro');
		return utf8_encode($mensagem);
	}

	protected function veioPorHttpRequestDe($modulo,$acao) {
		$primeiraAcao = $this->getContext()->getActionStack()->getFirstEntry();
		return
		$this->getRequest()->isXmlHttpRequest() &&
		$primeiraAcao->getActionName() == $acao &&
		$primeiraAcao->getModuleName() == $modulo;
	}

	/**
	 * Sets a flash variable that will be passed to the very next action.
	 *
	 * @param  string  The name of the flash variable
	 * @param  string  The value of the flash variable
	 * @param  boolean true if the flash have to persist for the following request (true by default)
	 */
	public function setFlash($name, $value, $persist = true)
	{
		$this->getUser()->setFlash($name, $value, $persist);
	}

	/**
	 * Gets a flash variable.
	 *
	 * @param  string The name of the flash variable
	 *
	 * @return mixed The value of the flash variable
	 */
	public function getFlash($name)
	{
		return $this->getUser()->getFlash($name);
	}

	/**
	 * Returns true if a flash variable of the specified name exists.
	 *
	 * @param  string The name of the flash variable
	 *
	 * @return boolean   true if the variable exists, false otherwise
	 */
	public function hasFlash($name)
	{
		return $this->getUser()->hasFlash($name);
	}

	public function setJSONJqGrid($data, $id)
	{
		$output	= array('total' 	=> ceil(count($data)/NUM_LIST_ITENS),
    					'page'		=> $this->getRequestParameter('page'),
    					'records'	=> count($data),
    					'rows'		=> array()
		);

		foreach($data as $chave => $dados)
		{
			$output['rows'][$chave]['id']	= $dados[$id];

			foreach($dados as $coluna => $valor)
			$output['rows'][$chave]['cell'][] = $valor;
		}

		$this->getResponse()->setHttpHeader('Content-type','application/json; charset=utf-8');
		return $this->renderText(json_encode($output));
	}

	public function getRequestDataTable()
	{
		$return	= array();

		//Colunas
		$this->colunas		= $this->getRequestParameter('columns');

		//Ordenação
		$array_colunas		= explode(",", $this->colunas);
		$this->order		= array('coluna' => $array_colunas[$this->getRequestParameter('iSortCol_0')],
									'direcao' => $this->getRequestParameter('sSortDir_0'));

		$this->search		= $this->getRequestParameter('sSearch');

		$this->filter      			= $this->_getFilter();
		$this->filter['search']		= $this->search;

		$this->page_num				= $this->getRequestParameter('iDisplayStart')+1;

		return $return;

	}


	public function paginadorDataTable($list, $paginaAtual = null, $limit = LIMIT_PAGE_DATA_TABLE, $url)
	{
		## cria o paginador

		$this->getContext()->getConfiguration()->loadHelpers('Url');

		$this->pager_layout = new Foxsis_Pager_Layout(
		$pager = new Doctrine_Pager(
		$list,
		($paginaAtual != null) ? $paginaAtual : $this->_setActualPage(),
		$limit
		),
		new Doctrine_Pager_Range_Sliding(array('chunk' => MAX_PAGER_LINKS)),
		url_for($url)
		);

		## executa a consulta
		$this->content = $this->pager_layout->execute(array(), Doctrine::HYDRATE_ARRAY);

		return  $this->content;
	}

	public function setJSONDataTable($data, $colunas, $total_linhas)
	{
		$output = array(
						"sEcho" 				=> intval($this->getRequestParameter('sEcho')),
						"iTotalRecords" 		=> $total_linhas,
    					"sColumns"				=> $colunas,
						"iTotalDisplayRecords" 	=> ceil($total_linhas/self::LIMIT_PAGE_DATA_TABLE),
						"aaData" 				=> array()
		);


		foreach($data as $chave => $dados)
		$output['aaData'][] = $dados;

		$this->getResponse()->setHttpHeader('Content-type','application/json; charset=utf-8');
		return $this->renderText(json_encode($output));
	}
}
?>